import _ from "lodash";
const scrollParent = (el) => {
  let parent = el.parentNode;
  while (parent) {
    if (/scroll/.test(getComputedStyle(parent)["overflow"])) {
      return parent;
    }
    parent = parent.parentNode;
  }
  return parent;
};

const render = (listener, status) => {
  let el = listener.el;
  let src = "";
  switch (status) {
    case "loading":
      src = listener.options.loading;
      break;
    case "loaded":
      src = listener.src;
      break;
    case "error":
      src = listener.options.error;
      break;
    default:
      barek;
  }
  el.setAttribute("src", src);
};
const loadImg = (src, resolve, reject) => {
  let img = new Image();
  img.src = src;
  img.onload = resolve;
  img.onerror = reject;
};
// 柯理化函数
const lazy = (Vue) => {
  class ReactiveListener {
    constructor({ el, src, options }) {
      // console.log(el, src);
      this.el = el;
      this.src = src;
      this.state = { loading: false };
      this.options = options;
    }
    checkInView() {
      // 用来检测自己在不在可视区域内
      // 获取当前元素 距离屏幕的位置
      let { top } = this.el.getBoundingClientRect();

      return top < window.innerHeight * this.options.preload;
    }
    load() {
      // 用来加载真实的图片路径
      // 显示loading图片
      // 在去加载真实内容， 图片成功后显示成功的内容， 失败显示失败的内容
      render(this, "loading");
      loadImg(
        this.src,
        () => {
          // success
          this.state.loading = true;
          render(this, "loaded");
        },
        () => {
          // fail
          render(this, "error");
        }
      );
    }
  }
  return class LazyClass {
    constructor(options) {
      //   super(props);
      this.options = options;
      this.bindHandler = false;
      this.listeners = [];
    }
    add(el, bindings, vnode) {
      console.log(el);

      // 2. 绑定滚动事件

      Vue.nextTick(() => {
        let ele = scrollParent(el);
        console.log(ele);
        // 1. 监控el 是否需要显示

        let listener = new ReactiveListener({
          el,
          src: bindings.value,
          options: this.options,
        });

        this.listeners.push(listener);

        if (!this.bindHandler) {
          // intersectionObserver
          // 降低频率用节流， 防抖就是最终值触发一次
          let lazyHandler = _.throttle(this.lazyLoadHandler.bind(this), 1000);
          ele.addEventListener("scroll", lazyHandler, {
            passive: false,
          });
          this.bindHandler = true;
        }
        this.lazyLoadHandler();
      });
    }
    lazyLoadHandler() {
      // console.log("scroll");
      // 看一下 哪些需要加载
      // 在可是区域内， 这个元素没有被加载过
      this.listeners.forEach((listener) => {
        if (listener.state.loading) return;
        // 如果自己在可视区域内， 就调用自己的加载方法即可
        listener.checkInView() && listener.load();
      });
    }
    remove() {}
  };
};
const VueLazyLoad = {
  install(Vue, options) {
    // lqip低质量图片
    console.log(Vue);
    console.log(options);
    const LazyClass = lazy(Vue);
    let instance = new LazyClass(options);
    Vue.directive("lazy", {
      //   bind() {},
      //   unbind() {},
      bind: instance.add.bind(instance),
      unbind: instance.remove.bind(instance),
    });
  },
};
export default VueLazyLoad;
